home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / MacApp Documentation / MacApp AppleLink Messages / MacApp.Tech$ 11⁄10⁄89 / 0041-More on Failure Hand-Nov89 < prev    next >
Encoding:
Text File  |  1989-11-10  |  2.6 KB  |  85 lines  |  [TEXT/GEOL]

  1. Item    9874114                         6-Nov-89        20:51
  2.  
  3. From:   PASCOE1                         Pascoe, Geoff
  4.  
  5. To:     MACAPP.TECH$                    MacApp Technical
  6.  
  7. Sub:    More on Failure Handlers
  8.  
  9. Larry Goldman,
  10.  
  11. Well, you called me on it!  Yep, your right!  In the initialization method the
  12. MacApp convention for allocating seems to be to set up a failure handler.  So,
  13. the routine that called New and IWhatever must be prepared to deal with an
  14. object handle that is no longer valid.  Apparently, if the routine is another
  15. initialization method the object is created into a temporary (you have to do
  16. this anyway since SELF may move when NEW is called) so if the initialization
  17. fails the calling initialization will unroll from that point leaving the
  18. original instance variable still NIL.  That is,
  19.  
  20. TFoo.IFoo;
  21.  
  22.     VAR
  23.  
  24.         aBar : TBar;
  25.         fi : FailInfo;
  26.  
  27.     FooHandler(.....);
  28.  
  29.         BEGIN {FooHandler}
  30.             SELF.Free
  31.         END; {FooHandler}
  32.  
  33.     BEGIN {TFoo.IFoo}
  34.         fBar := NIL;    (* We'll want this to point to a TBar. *)
  35.  
  36.         INHERITED ISuperFoo;    (* If we fail here we're OK if in Free we   *)
  37.                                 (* FreeIfObject(fBar).                      *)
  38.  
  39.         CatchFailures(fi, FooHandler)
  40.            NEW(aBar);
  41.            FailNIL(aBar);
  42.            aBar.IBar;       (* If we fail here aBar will reclaim itself.    *)
  43.            fBar := aBar;    (* Since we set fBar only after we succeed      *)
  44.         Success(fi)         (* TFoo.Free won't try to free the instance of  *)
  45.                             (* TBar twice.                                  *)
  46.      END; {TFoo.IFoo}
  47.  
  48. TBar.IBar
  49.  
  50.     VAR
  51.  
  52.         aBlob : Handle;
  53.         fi : FailInfo;
  54.  
  55.     BarHandler(.......)
  56.  
  57.         BEGIN {BarHandler}
  58.             DisposIfHandle(aBlob);
  59.             SELF.Free
  60.         END; {BarHandler}
  61.  
  62.     BEGIN {TBar.IBar}
  63.         fBlob := NIL;
  64.  
  65.         INHERITED ISuperBar;
  66.  
  67.         CatchFailures(fi, BarHandler);
  68.             aBlob := NewHandle(someSize);   (* Don't assign to instVar here  *)
  69.             fBlob := aBlob                  (* since SELF can move.          *)
  70.         Success(fi)
  71.  
  72.     END; {TBar.IBar}
  73.  
  74. Another POSSIBLE convention would be to have all the creating procedures
  75. responsible for freeing.  In this case IFoo would free aBar and the caller of
  76. IFoo would free the Foo.  That way the handle is always valid but the
  77. responsibility is pushed one level out.  I don't think this is quite as nice as
  78. the current scheme.  Did I get it right this time?
  79.  
  80. Incidentally, is the failure handling mechanism fully reentrant?  That is, can
  81. I set up a failure handler inside a failure handler?
  82.  
  83. Geoff
  84.  
  85.